package com.ld.security.common.core.util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class MapUtil {

    public interface  NodeLast<E>{
        /**
         * 最后一层节点处理
         * @param map
         * @param i
         * @return
         */
        Map run(Map<?,List<E>> map,int i);
    }


    public static final NodeLast node_one= (map, i) -> {
        Map v = new HashMap<>();
        for (Object x : map.keySet()) {
            Object va =  map.get(x);
            List y = (List) va;
            if (y.size() == 1) {
                Object val = y.get(0);
                v.put(x, val);
            } else {
                v.put(x, y);
            }
        }
        return v;
    };

    public static final NodeLast node_list= (map, i) -> {
        return map;
    };
    public  static <E,K> Map<K,List<E>> group(List<E> objs,String fieldKey){
         return objs.stream().collect(Collectors.groupingBy(v -> {
            return ReflectionUtil.invokeGetter(v,fieldKey);
        }));
    }

  public static <E> Map groupList(List<E> list, List<String> keys,NodeLast nodeLast) {
        return groupList(list,keys,0,nodeLast);
  }


    public static <E> Map groupList(List<E> list, String... keys) {
        return groupList(list, Arrays.asList(keys),node_list);
    }


    private static <E> Map groupList(List<E> list,List<String> keys,int i,NodeLast nodeLast){

        Map val = null;
        String key = keys.get(i);
        Map<?,List<E>> map =  group(list,key);

        //最后一层预处理
        if(i + 1 == keys.size()){
            val =  nodeLast.run(map,i);
        }else{
            val = map;
        }

        if(i + 1 < keys.size() ){
            for (Object s : map.keySet()) {
                List<E> y =  map.get(s);
                Map v =  groupList(y,keys,i + 1,nodeLast);
                val.put(s,v);
             }
        }
        return val;
    }

        public  static <K,V> Map<K,V>  objToMap(List objs,String fieldKey){
        return objToMap(objs,"",fieldKey);
    }



        public  static <K,V> Map<K,V> objToMap( List objs,String split,String... keys){
        HashMap map = new HashMap<>();
        for (Object obj : objs) {
            String key = "";
            boolean b=true;
          for (String fieldKey : keys) {
              if(b){
                  key+=split;
              }else{
                  b=false;
              }
              Object key0 =  ReflectionUtil.invokeGetter(obj,fieldKey);
              key+=key0;
          }
            map.put(key,obj);
        }
        return map;
    }

}
